const HtmlWebpackPlugin = require("html-webpack-plugin");
const TerserPlugin = require("terser-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
const { ProvidePlugin } = require("webpack");
const path = require("path");

const devConfig = require("./dev.config");
const prdConfig = require("./prod.config");
const { merge } = require("webpack-merge");
const prodConfig = require("./prod.config");

// const SpeedMeasurePlugin = require("speed-measure-webpack-plugin");

// const smp = new SpeedMeasurePlugin();

const commonConfig = isProduction => {
  return {
    entry: "./src/main.js",
    resolve: {
      extensions: [".js", ".json", ".wasm", ".ts", ".tsx"], //文件扩展
    },
    // entry: {
    //   index: {
    //     import: "./src/index.js",
    //     dependOn: "shared",
    //   },
    //   main: {
    //     import: "./src/main.js",
    //     dependOn: "shared",
    //   },
    //   shared: ["axios"], //共享的文件
    //   shared1: ["dayjs"], //共享的文件
    //   shared2: ["react"], //共享的文件
    // }, //多入口
    output: {
      path: path.resolve(__dirname, "../dist"), // 打包出口必须是绝对路径
      //placeholder  多入口，打包之后webpack无法识别要输出到哪个文件，需要占位符
      filename: "[name]_bundle.js",
      // assetModuleFilename:'abc.png'//打包后的静态资源重命名
      clean: true, // 在生成文件之前清空 output 目录 cleanWebpackPlugin
      chunkFilename: "[name]_chunk.js", //动态引入的文件分包名称重命名，或者单独针对分包文件
      // publicPath: "https://www.baidu.com/cdn/", //配置cdn地址
    },
    module: {
      rules: [
        {
          test: /.css$/i, // 匹配打包后缀为css的文件
          use: [isProduction ? MiniCssExtractPlugin.loader : "style-loader", "css-loader"], //单独抽离css文件
          // use: ["style-loader", "css-loader"], // 顺序必须为 style-loader css-loader，loader使用顺序从右到左
          //只有一个简写
          // loader:'css-loader',
          //方式二
          // use: [{ loader: "style-loader" }],
        },
        {
          test: /.less$/,
          use: ["style-loader", "css-loader", "less-loader"],
        },
        {
          //对于图片，webpack内置了对于的loader
          test: /\.(png|jpg|jpe?g|svg|gif)$/,
          //打包两张图片，并且这两张图片有自己的地址
          // type:"asset/resource"
          //将图片base64编码，将编码后的源码放到js文件中
          //优缺点：相对于上面，减少http请求，不需要再去请求图片，缺点：导致js文件很大，下载时间过长，会阻塞后续解析
          //对于小图片可以base64编码，对于大文件，可以额外去请求
          // type: "asset/inline",
          type: "asset", //资源类型，webpack5内置
          parser: {
            dataUrlCondition: {
              maxSize: 60 * 1024,
            },
          },
          generator: {
            //img:生成img文件夹
            //name：指向原来的图片名称
            //ext：扩展名
            //hash：打包后生成的hash值  :8 截取8位
            filename: "image/[name]_[hash:8][ext]",
          },
        },
        {
          test: /\.js$/,
          use: [
            {
              loader: "babel-loader",
              options: {
                plugins: ["@babel/plugin-transform-arrow-functions"],
              },
            },
          ],
        },
      ],
    },
    plugins: [
      new HtmlWebpackPlugin({
        title: "webpack学习", //标签页对应的title
        cache: true, //缓存
        template: "./index.html", //指定模板
        minify: isProduction
          ? {
              //压缩的时候移除注释
              removeComments: true,
              //移除空属性 例如 标签上有style属性，但没写样式
              removeEmptyAttributes: true,
              //移除多余属性，比如input 标签 type=text
              removeEmptyAttributes: true,
              //折叠空白字符
              collapseWhitespace: true,
              //压缩内联的css
              minifyCSS: true,
              //压缩js代码
              minifyJS: {
                mangle: {
                  toplevel: true,
                },
              },
            }
          : false, //html压缩
      }), //生成html文档
      new ProvidePlugin({
        axios: ["axios", "default"],
        dayjs: "dayjs",
      }), //shimming
    ],
  };
};

module.exports = function (env) {
  const isProduction = env.production;
  const mergeConfig = isProduction ? prodConfig : devConfig;
  const finalConfig = merge(mergeConfig, commonConfig(isProduction));
  return finalConfig;
  // return smp.wrap(finalConfig);
};
